package cn.org.cute.ebocy.util;

import java.util.*;

/**
 * 实现类似Hashtable的按键名检索算法。
 */

public class SpeedSearcher<T>{
	
	private String[] names;
	private T[] values;
	
	/**
     * Constructor.
     * @param ht 包含键-值对的Hashtable
     */
	public SpeedSearcher(Hashtable<String, T> ht){
		
		if(ht == null){
			return;
		}

		Object[] os = ht.keySet().toArray();
		int l = os.length;
		String n;
		
		names = new String[l];
		values = (T[]) new Object[l];
		
		for(int i=0;i<l;i++){
			n = (String) os[i];
			names[i] = n;
			values[i] = ht.get(n);
		}
		
		swap();
		
	}

	public SpeedSearcher(ArrayList<T> al, Searchable<String, T> search){
		
		if(al == null || search == null){
			return;
		}
		
		int size = al.size();
		T temp = null;
		names = new String[size];
		values = (T[]) new Object[size];
		
		for(int i=0;i<size;i++){
			temp = al.get(i);
			names[i] = search.getKey(temp);
			values[i] = temp;
		}
		
		swap();
		
	}
	
	private void swap(){
		
		int x;
		int j;
		
		int l = names.length;
		
		for(int i=0;i<l;i++){
			x = i;
			for(j=i+1;j<l;j++){
				if(names[x].compareTo(names[j]) > 0){
					x = j;
				}
			}
			if(i != x){
			    swap(names,i,x);
			    swap(values,i,x);
			}
		}
				
	}
	
	private void swap(Object[] o,int i,int x){
		Object t = o[i];
		o[i] = o[x];
		o[x] = t;
	}
	
	/**
     * 检索键对应的值。
     * @param name 键名
     * @return 键对应的值
     */
	public T get(String name){
		if(name == null){
			return null;
		}
		int p = Arrays.binarySearch(names,name);
		return p >= 0 ? values[p] : null;
	}
	/**
     * 设置键-值
     * @param name 键名
     * @return value 键值
     */
	public void replace(String name,T value){
		int p = Arrays.binarySearch(names,name);
		if(p >= 0){
			values[p] = value;
		}
	}
	
	public String[] keys(){
		return names;
	}
	
	public T[] values(){
		return values;
	}
	
}
